import os
import time
from utils.mylib_utils import *
from measurement.preprocess_probe_data import *
import multiprocessing

db_path_config_table = "bt_system_path_config"


def apiCallSimulationUncertainty(param):
    """
    调用第三方仿真模拟程序
    """
    print("进入仿真模拟调用过程..")
    print("参数情况：")
    print(param)

    # 参数处理
    task_id = param.get('task_id') if param.get('task_id') is not None else get_current_timestamp()                     # TaskId默认为当前时间
    user_id = int(param.get('user_id')) if param.get('user_id') is not None else -1                                     # 当前登录用户

    program_path = param.get('program_path') if param.get('program_path') is not None else ""                           # 仿真模拟程序路径
    input_device_parameter_file = param.get('input_device_parameter_file') if param.get('input_device_parameter_file') is not None else ""      # 设备参数文件
    output_uncertainty_file = param.get('output_uncertainty_file') if param.get('output_uncertainty_file') is not None else ""                  # 不确定度分量文件输出目录（从数据表bt_system_path_config获取“UncertaintyComponentFilePath”的值）

    conf = {
        "TaskId": task_id,
        # 任务种类：0:数据录入；1:数据预处理；2:不确定度评定;3:数据分析数据处理;
        # 5:一键评定;6:评定结果查询（文件上传）；7:不确定度校验（文件上传）；8:数据比对不同设备；9:数据比对不同时间
        # 10. 仿真模拟调用
        "TaskType": 10,
        "UserId": user_id,

        #
        "ProgramPath": program_path,
        "InputDeviceParamaterFile": input_device_parameter_file,
        "OutputUncertaintyPath": output_uncertainty_file,
    }

    print("参数值：")
    print(conf)

    program_path, output_uncertainty_path = getSimulationPath()
    if conf['ProgramPath'] == "":
        conf['ProgramPath'] = program_path
    if conf['OutputUncertaintyPath'] == "":
        conf['OutputUncertaintyPath'] = output_uncertainty_path

    # 判断参数合法性
    if not os.path.isfile(conf['ProgramPath']):
        print("仿真可执行文件路径错误!")
        print(conf['ProgramPath'])
        return {"code": -1, "msg": "仿真可执行文件路径错误！"}
    if not os.path.exists(conf['OutputUncertaintyPath']) or os.path.isfile(conf['OutputUncertaintyPath']):
        print("仿真结果目录不存在或设置错误！")
        print(conf['OutputUncertaintyPath'])
        return {"code": -1, "msg": "仿真结果目录不存在或设置错误！"}
    if not os.path.isfile(conf['InputDeviceParamaterFile']):
        print("未找到设备参数文件！")
        print(conf['InputDeviceParamaterFile'])
        return {"code": -1, "msg": "未找到设备参数文件！"}

    # 合理参数
    print(conf)

    # 设置任务开始
    TASK_ID = conf['TaskId']
    if TASK_ID != "":
        ret = setTaskStatus(TASK_ID, conf['TaskType'], 0)
        if ret != "OK":
            print("setTaskStatus: %s" % ret)
            return ret

    # 对data_head_id_list中的所有数据进行高度分辨率处理和时间分辨率处理
    processes = []
    process = multiprocessing.Process(target=apiCallThridProgram, args=(conf, TASK_ID))
    processes.append(process)
    process.start()

    return 0


def apiCallThridProgram(conf, TASK_ID):
    # python test_simu_v2.py D:/GBfiles/mycode/Workspace/MeasurementProject/test_data/探测设备参数csv文件/dataInput_Lidar02_RamT.csv D:/tmp/callsimulationprogram_test
    if checkLinuxOrWindows() == 1:
        python_command = "python3"
    else:
        python_command = "python"

    command_str = "%s %s %s %s" % (python_command, conf['ProgramPath'], conf['InputDeviceParamaterFile'], conf['OutputUncertaintyPath'])
    print("执行仿真命令：%s" % command_str)
    # 数据读取计时开始：
    start_time1 = time.time()

    os.system(command_str)

    # 数据读取计时结束：
    end_time1 = time.time()
    # 计算代码运行时间(ms)
    run_time = (end_time1 - start_time1) * 1000
    print("仿真模拟执行时间（ms）：")
    print(run_time)

    # 设置任务结束
    print("将要设置任务结束..")
    if TASK_ID != "":
        print("设置任务结束！")
        updateTaskStatus(TASK_ID, conf['TaskType'])

    return 0


def getSimulationPath():
    program_path = ""
    output_uncertainty_path = ""

    query_conditon = 'True'
    print("query_conditon: %s" % query_conditon)
    ret = select_db(db_path_config_table, query_conditon)
    # print(ret, len(ret))
    if len(ret) > 0:
        ret = dbQueryResult2JsonObj(ret, db_path_config_table)
        print(ret)
        for item in ret:
            if item['ConfigName'] == "SimulationModulePath":
                program_path = item['ConfigPath']
            elif item['ConfigName'] == "UncertaintyComponentFilePath":
                output_uncertainty_path = item['ConfigPath']
    else:
        print("Error: 仿真模拟配置信息未找到！")

    if program_path == "" or output_uncertainty_path == "":
        print("仿真模拟参数信息获取失败！")

    return program_path, output_uncertainty_path
